export class Iterator {
  constructor(root) {
    const node = this.#createNode(root);
    this.nextNode = node;
    if (this.#hashChildren(node)) {
      const children = this.#getChildren(node);
      this.#setChildrenRelation(children);
    }
  }

  next() {
    // debugger;
    const node = this.nextNode;
    // 有孩子，给孩子设置parent和sibling
    if (this.#hashChildren(node)) {
      const children = this.#getChildren(node);
      this.#setChildrenRelation(children);
      // 设置下一个节点
      this.nextNode = children[0];
    } else {
      // 设置下一个节点，兄弟节点或其他树枝上的兄弟节点
      this.nextNode = this.#getSibling(node);
    }

    return node;
  }

  hasNext() {
    return this.nextNode !== null;
  }

  #createNode(leaf) {
    return Object.assign({}, leaf, { parent: null, sibling: null });
  }

  #setChildrenRelation(children) {
    // 虽然执行了3次循环，但是能将设置节点对象，设置parent，设置sibling解耦
    children.forEach((child, idx) => {
      children[idx] = this.#createNode(child);
    });
    this.#setChildrenParent(children);
    this.#setChildrenSibling(children);
  }

  #setChildrenParent(children) {
    children.forEach((child, i) => {
      children[i].parent = this.nextNode;
    });
  }

  #setChildrenSibling(children) {
    children.reduce((pre, cur, idx) => {
      if (idx > 0) {
        pre.sibling = cur;
      }
      return cur;
    }, null);
  }

  #hashChildren(node) {
    return node.props.children?.length > 0;
  }
  #getChildren(node) {
    return node.props.children;
  }

  #getSibling(node) {
    if (node.sibling) {
      return node.sibling;
    }
    // 没有parent，最后的节点，
    if (!node.parent) return null;
    // 有parent，查找parent的sibling
    return this.#getSibling(node.parent);
  }
}
